package me.zhenqu.services;

import me.zhenqu.model.bo.PascodeBo;
import me.zhenqu.model.bo.StatusBo;
import me.zhenqu.model.bo.TimeLineBo;
import me.zhenqu.model.bo.UserBo;
import me.zhenqu.model.pojo.entity.Pascode;
import me.zhenqu.model.pojo.entity.Status;
import me.zhenqu.model.pojo.entity.User;
import me.zhenqu.services.cache.CacheMaker;
import me.zhenqu.services.factory.CipherUtil;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: yibing.tan
 * Date: 11-11-3
 * Time: 上午10:03
 * To change this template use File | Settings | File Templates.
 */
public class UserService {
    @Autowired
    UserBo bo;

    @Autowired
    TimeLineBo timeLineBo;

    @Autowired
    PascodeBo pascodeBo;

    @Autowired
    StatusBo statusBo;

    @Autowired
    CacheMaker cacheMaker;

    public void setBo(UserBo bo) {
        this.bo = bo;
    }

    public void setPascodeBo(PascodeBo pascodeBo) {
        this.pascodeBo = pascodeBo;
    }

    public void setCacheMaker(CacheMaker cacheMaker) {
        this.cacheMaker = cacheMaker;
    }

    public void setTimeLineBo(TimeLineBo timeLineBo) {
        this.timeLineBo = timeLineBo;
    }

    public void setStatusBo(StatusBo statusBo) {
        this.statusBo = statusBo;
    }

    public User getById(Long id) {
        User existent = cacheMaker.getUserFromCache(id);
        if (existent!=null) return existent;
        existent = bo.findByID(id);
        if (existent!=null)
            cacheMaker.saveUser(existent);
        return existent;
    }

    public List<User> mgetByIds(Collection<Long> ids) {
        List<User> users = new LinkedList<User>();
        if (ids==null||ids.isEmpty()) return users;
        for (Long id: ids)
            users.add(getById(id));
        return users;
    }

    public User signIn(String nick_name, String password){
        User existent = findByNickName(nick_name);
        if (existent==null||existent.getUser_id()==0)
            throw new RuntimeException("用户不存在:"+nick_name);
        long uid = existent.getUser_id();
        Pascode pascode = pascodeBo.findByID(uid);
        if (pascode==null)
            throw new RuntimeException("密码未设置:"+nick_name);
        String upass = pascode.getPassword();
        if (upass==null||!CipherUtil.validatePassword(upass, password))
            throw new RuntimeException("用户名密码不符:"+nick_name);
        return existent;
    }

    public void createUser(User user, Pascode pascode){
        long uid = save(user);
        pascode.setUser_id(uid);
        pascode.setPassword(CipherUtil.generatePassword(pascode.getPassword()));
        savePascode(pascode);
    }

    public long save(User value) {
        bo.save(value);
        cacheMaker.saveUser(value);
        return bo.findByNickName(value.getNick_name()).getUser_id();
    }

    public void savePascode(Pascode value) {
        pascodeBo.save(value);
    }

    public void delete(User value) {
        bo.delete(value);
        cacheMaker.delete(value);
    }

    public void update(User value) {
        bo.update(value);
        cacheMaker.updateCache(value);
    }

    public User findByNickName(String nick_name){
        return bo.findByNickName(nick_name);
    }

    public void deletePascode(Pascode ps) {
        pascodeBo.delete(ps);
    }

    public List<User> loadFollowingUserIds(Long user_id){
        List<Long> followingIds = bo.loadFollowingUserIds(user_id);
        List<User> result = new LinkedList<User>();
        if (followingIds==null||followingIds.isEmpty()) return result;
        return mgetByIds(followingIds);
    }

    public List<User> loadFollowedUserIds(Long user_id){
        List<Long> followedIds = bo.loadFollowedUserIds(user_id);
        List<User> result = new LinkedList<User>();
        if (followedIds==null||followedIds.isEmpty()) return result;
        return mgetByIds(followedIds);
    }

    public List<User> searchUserIds(String keyword){
        return bo.search(keyword);
    }

    public void follow(Long user_id, Long targetId){
        bo.follow(user_id, targetId);
        List<Status> statusList = statusBo.findUserStatusSince(targetId,0);
        for (Status status: statusList)
            CommonService.updateTimeLine(status, user_id, timeLineBo);
    }

    public void unfollow(Long user_id, Long targetId){
        bo.unfollow(user_id, targetId);
        List<Status> statusList = statusBo.findUserStatusSince(targetId, 0);
        for (Status status: statusList)
            CommonService.deleteTimeLine(status, user_id, timeLineBo);
    }

    public boolean isFollowing(Long user_id, Long targetId){
        return bo.isFollowing(user_id, targetId);
    }

    public boolean isFollowed(Long user_id, Long targetId){
        return bo.isFollowed(user_id, targetId);
    }

    public User signup(String nick_name, String password){
        User existent = findByNickName(nick_name);
        if (existent!=null&&existent.getUser_id()!=0)
        {
            System.err.println("nick_name exist:"+nick_name);
            return null;
        }
        existent = new User();
        existent.setNick_name(nick_name);
        Pascode pascode = new Pascode();
        pascode.setPassword(password);
        pascode.setLast_login_in(System.currentTimeMillis());
        try{
            createUser(existent, pascode);
        }catch (RuntimeException e){
            return null;
        }
        return findByNickName(nick_name);
    }


}
